#include "insn.h"
#include <stdio.h>


void kyber512_keygen(void){
//opcode, func3, func7, rd, rs1, rs2
		//SHA3_Enable,6'b000001
		//rs1=d rs2=0 dst=9    	//G（Seed）000
		asm volatile (".insn r 0x0b, 0, 0b0000001, x9, x9, x0");

		//SHA3_Enable,6'B011000
		//rs1=σ rs2=0 dst=0  	//采样s0 000
		asm volatile (".insn r 0x0b, 0, 0b0011000, x0, x10, x0");

		//Poly_Enable,`NTT
		//rs1=0 rs2=0 dst=0    //NTT s0 001 RAM3+RAM1第一轮 to RAM2
		asm volatile (".insn r 0x2b, 0, 0b0000000, x16, x0, x0");

		//SHA3_Enable,6'B011001
		//rs1=σ rs2=0 dst=1	//采样s1 000
		asm volatile (".insn r 0x0b, 0, 0b0011001, x1, x10, x0");

		//Poly_Enable,`NTT
		//rs1=0 rs2=1 dst=1   //NTT s1 001 RAM3+RAM1第一轮 to RAM2
		asm volatile (".insn r 0x2b, 0, 0b0000000, x17, x0, x1");



		//SHA3_Enable,6'B100000
		//rs1=ρ rs2=0 dst=0		//采样 AT 00  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100000, x0, x9, x0");


		//Poly_Enable,`PWM1
		//rs1=0 rs2=0 dst=0		//A00 s0 PWM1 100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x16, x0");
		//SHA3_Enable,6'B100001
		//rs1=ρ rs2=0 dst=1		//采样 AT 01  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100001, x1, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=2		//A00 s0  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x18, x0, x1");


		//Poly_Enable,`PWM1
		//rs1=1 rs2=1 dst=0		//A01 s1 PWM1    100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x17, x1");
		//SHA3_Enable,6'B100001
		//rs1=ρ rs2=0 dst=2		//采样 AT 10  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100100, x2, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=3		//A01 s1  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x19, x0, x1");


		//Poly_Enable,`PWM1
		//rs1=0 rs2=2 dst=0		//A10 s0 PWM1    100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x16, x2");
		//SHA3_Enable,6'B100001
		//rs1=ρ rs2=0 dst=3		//采样 AT 11  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100101, x3, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=4		//A10 s0  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x20, x0, x1");

		//Poly_Enable,`PWM1
		//rs1=1 rs2=3 dst=0		//A11 s1 PWM1    100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x17, x3");
		//SHA3_Enable,6'B011010
		//rs1=σ rs2=0 dst=4		//采样e0
		asm volatile (".insn r 0x0b, 0, 0b0011010, x4, x10, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=5		//A11 s1  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x21, x0, x1");


		//Poly_Enable,`NTT
		//rs1=6 rs2=4 dst=2		//NTT e0   100
		asm volatile (".insn r 0x2b, 0, 0b0000000, x2, x22, x4");


		//SHA3_Enable,6'B011011
		//rs1=σ rs2=0 dst=5		//采样e1
		asm volatile (".insn r 0x0b, 0, 0b0011011, x5, x10, x0");
		//Poly_Enable,`NTT
		//rs1=6 rs2=5 dst=3		//NTT e1   100
		asm volatile (".insn r 0x2b, 0, 0b0000000, x3, x22, x5");


		//Poly_Enable,`PolyAdd
		//rs1=2 rs2=3 dst=0		//A01s1+A00s0  110  RAM2+RAM2=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x0, x18, x19");

		//`Poly_Enable,`PolyAdd
		//rs1=4 rs2=5 dst=1		//A11s1+A10s0  110  RAM2+RAM2=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x1, x20, x21");


		//Poly_Enable,`PolyAdd
		//rs1=0 rs2=2 dst=6		//A01s1+A00s0+e0  001  RAM3+RAM3=RAM2
		asm volatile (".insn r 0x2b, 0, 0b0000100, x22, x0, x2");

		//Poly_Enable,`PolyAdd
		//rs1=1 rs2=3 dst=7		//A11s1+A10s0+e1  001  RAM3+RAM3=RAM2
		asm volatile (".insn r 0x2b, 0, 0b0000100, x23, x1, x3");

		//wait inst 0010000
		asm volatile (".insn r 0x7b, 0, 0b0010000, x0, x0, x0");
		//存储keygen后的随机数ρ，sk，pk

}

void kyber512_enc(void){
//opcode, func3, func7, rd, rs1, rs2
		//SHA3_Enable,6'b110000
		//rs1=m rs2=0 dst=额外地址8		//H（m） 256bit
		asm volatile (".insn r 0x0b, 0, 48, x8, x8, x0");
		//SHA3_Enable,6'b110001
		//rs1=10 rs2=ρ dst=10			//H（pk）  256bit
		asm volatile (".insn r 0x0b, 0, 49, x10, x10, x9");
		//SHA3_Enable,6'b000010
		//rs1=8 rs2=10 dst=11			//G(m|Hpk) K 512bit
		asm volatile (".insn r 0x0b, 0, 2, x11, x8, x10");
		//SHA3_Enable,6'B011000
		//rs1=r rs2=0 dst=0				//采样r0
		asm volatile (".insn r 0x0b, 0, 24, x0, x12, x0");

		//Poly_Enable,`NTT
		//rs1=0 rs2=0 dst=0				//NTT r0 001 RAM3+RAM1第一轮 to RAM2
		asm volatile (".insn r 0x2b, 1, 0, x16, x0, x0");

		//SHA3_Enable,6'B011001
		//rs1=r rs2=0 dst=1				//采样r1
		asm volatile (".insn r 0x0b, 0, 25, x1, x12, x0");

		//Poly_Enable,`NTT
		//rs1=0 rs2=1 dst=1				//NTT r1 001 RAM3+RAM1第一轮 to RAM2
		asm volatile (".insn r 0x2b, 1, 0, x17, x0, x1");



		//`SHA3_Enable,6'B100000
		//rs1=ρ rs2=0 dst=2				//采样 AT 00  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100000, x2, x9, x0");

		//Poly_Enable,`PWM1
		//rs1=0 rs2=2 dst=0		//A00 r0 PWM1 100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x16, x2");
		//SHA3_Enable,6'B100100
		//rs1=ρ rs2=0 dst=3				//采样 AT 01  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100100, x3, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=2		//A00 r0 PWM2 001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x18, x0, x1");


		//Poly_Enable,`PWM1
		//rs1=1 rs2=3 dst=0		//A01 r1 PWM1 100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x17, x3");
		//SHA3_Enable,6'B100100
		//rs1=ρ rs2=0 dst=4				//采样 AT 10  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100001, x4, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=3		//A01 r1 PWM2 001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x19, x0, x1");

		//Poly_Enable,`PWM1
		//rs1=0 rs2=4 dst=0		//A01 r1 PWM1 100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x16, x4");
		//SHA3_Enable,6'B100101
		//rs1=ρ rs2=0 dst=5				//采样 AT 11  ρ
		asm volatile (".insn r 0x0b, 0, 0b0100101, x5, x9, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=4		//A01 r1 PWM2 001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x20, x0, x1");

		//Poly_Enable,`PWM1
		//rs1=1 rs2=5 dst=0		//A11 s1 PWM1    100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x0, x17, x5");
		//SHA3_Enable,6'B010010
		//rs1=r rs2=0 dst=0		//采样e10
		asm volatile (".insn r 0x0b, 0, 0b0010010, x0, x12, x0");
		//Poly_Enable,`PWM2
		//rs1=0 rs2=1 dst=5		//A11 s1  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x21, x0, x1");

		//Poly_Enable,`PolyAdd
		//rs1=2 rs2=3 dst=0		//A01r1+A00r0=u[0]  110  RAM2+RAM2=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x0, x18, x19");
		//SHA3_Enable,6'B010011
		//rs1=r rs2=0 dst=1		//采样e11
		asm volatile (".insn r 0x0b, 0, 0b0010011, x1, x12, x0");
		//Poly_Enable,`PolyAdd
		//rs1=4 rs2=5 dst=1		//A11r1+A10r0=u[1]  110  RAM2+RAM2=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x1, x20, x21");

		//Poly_Enable,`INTT
		//rs1=0 rs2=0 dst=2		//intt u[0]  001
		asm volatile (".insn r 0x2b, 0, 0b0000001, x18, x0, x0");
		//SHA3_Enable,6'B010100
		//rs1=r rs2=0 dst=2		//采样e2
		asm volatile (".insn r 0x0b, 0, 0b0010100, x2, x12, x0");
		//Poly_Enable,`INTT
		//rs1=1 rs2=0 dst=3		//intt u[1]  001
		asm volatile (".insn r 0x2b, 0, 0b0000001, x19, x1, x0");
		//Poly_Enable,`PolyAdd
		//rs1=2 rs2=0 dst=0		//e10+u[0]  100  RAM2+RAM1=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x0, x18, x0");
		//Poly_Enable,`PolyAdd
		//rs1=3 rs2=1 dst=1		//e11+u[1]  100  RAM2+RAM1=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x1, x19, x1");

		//Poly_Enable,`PWM1
		//rs1=0 rs2=10 dst=2	//r0*t0  PWM1  100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x2, x16, x10");
		//Poly_Enable,`PWM2
		//rs1=2 rs2=3 dst=4		//r0*t0  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x20, x2, x3");

		//Poly_Enable,`PWM1
		//rs1=1 rs2=11 dst=2	//r1*t1  PWM1  100
		asm volatile (".insn r 0x2b, 0, 0b0000010, x2, x17, x11");
		//Poly_Enable,`PWM2
		//rs1=2 rs2=3 dst=5		//r1*t1  PWM2   001
		asm volatile (".insn r 0x2b, 0, 0b0000011, x21, x2, x3");

		//Poly_Enable,`PolyAdd
		//rs1=4 rs2=5 dst=2		//r0t0+r1t1  110  RAM2+RAM2=RAM3
		asm volatile (".insn r 0x2b, 0, 0b0000100, x2, x20, x21");

		//Poly_Enable,`INTT
		//rs1=2 rs2=0 dst=2		//intt tr  001
		asm volatile (".insn r 0x2b, 0, 0b0000001, x18, x2, x0");

		//Poly_Enable,`Encode_ADD
		//rs1=2 rs2=2 dst=3		//encode_add tr+e2+m  000
		asm volatile (".insn r 0x2b, 0, 0b0000101, x3, x2, x2");


		/////////////////////////////压缩/////////////////////////
		//Poly_Enable,`Compress10
		//rs1=0 rs2=0 dst=3		//RAM3 to RAM2  001 Compress10
		asm volatile (".insn r 0x2b, 0, 0b0100000, x19, x0, x0");
		//Poly_Enable,`Compress10
		//rs1=1 rs2=0 dst=4		//RAM3 to RAM2  001 Compress10
		asm volatile (".insn r 0x2b, 0, 0b0100000, x20, x1, x0");
		//Poly_Enable,`Compress4
		//rs1=3 rs2=0 dst=5		//RAM3 to RAM2  001 Compress4
		asm volatile (".insn r 0x2b, 0, 0b0100001, x21, x3, x0");

		//wait inst 0010000
		asm volatile (".insn r 0x7b, 0, 0b0010000, x0, x0, x0");

		//SHA3_Enable,6'b110100
		//rs1=3 rs2=5 dst=3		//Hc 110
		asm volatile (".insn r 0x0b, 0, 0b0110100, x3, x19, x21");

		//SHA3_Enable,6'b011110
		//rs1=11 rs2=3 dst=11	//KDF（K||Hc） 000
		asm volatile (".insn r 0x0b, 0, 0b0011110, x11, x11, x3");
		//wait inst 0010000
		asm volatile (".insn r 0x7b, 0, 0b0010000, x0, x0, x0");
}

void kyber512_dec(void){
/////////////////////////////解压/////////////////////////
	//Poly_Enable,`DeCompress10
	//rs1=0 rs2=0 dst=0		//RAM2 to RAM3  100 DeCompress10
	asm volatile (".insn r 0x2b, 0, 0b0101000, x0, x16, x0");
	//Poly_Enable,`DeCompress10
	//rs1=1 rs2=0 dst=1		//RAM2 to RAM3  100 DeCompress10
	asm volatile (".insn r 0x2b, 0, 0b0101000, x1, x17, x0");
	//Poly_Enable,`DeCompress4
	//rs1=2 rs2=0 dst=2		//RAM2 to RAM3  100 DeCompress10
	asm volatile (".insn r 0x2b, 0, 0b0101001, x2, x18, x0");

	//Poly_Enable,`NTT
	//rs1=0 rs2=0 dst=0    //NTT u0 011 RAM3 to RAM2
	asm volatile (".insn r 0x2b, 0, 0b0000000, x16, x0, x16");
	//Poly_Enable,`NTT
	//rs1=1 rs2=0 dst=1    //NTT u1 011 RAM3 to RAM2
	asm volatile (".insn r 0x2b, 0, 0b0000000, x17, x1, x16");

	//Poly_Enable,`PWM1
	//rs1=0 rs2=8 dst=3	//u0*s0  PWM1  100
	asm volatile (".insn r 0x2b, 0, 0b0000010, x3, x16, x8");
	//Poly_Enable,`PWM2
	//rs1=3 rs2=4 dst=2		//u0*s0  PWM2   001
	asm volatile (".insn r 0x2b, 0, 0b0000011, x18, x3, x4");

	//Poly_Enable,`PWM1
	//rs1=1 rs2=9 dst=3	//u1*s1  PWM1  100
	asm volatile (".insn r 0x2b, 0, 0b0000010, x3, x17, x9");
	//Poly_Enable,`PWM2
	//rs1=3 rs2=4 dst=3		//u1*s1  PWM2   001
	asm volatile (".insn r 0x2b, 0, 0b0000011, x19, x3, x4");

	//Poly_Enable,`PolyAdd
	//rs1=2 rs2=3 dst=3		//u0s0+u1s1  110  RAM2+RAM2=RAM3
	asm volatile (".insn r 0x2b, 0, 0b0000100, x3, x18, x19");

	//Poly_Enable,`INTT
	//rs1=3 rs2=0 dst=4		//intt su  001
	asm volatile (".insn r 0x2b, 0, 0b0000001, x20, x3, x0");

	//SHA3_Enable,6'b110001
	//rs1=10 rs2=ρ dst=11	//H（pk） 000
	asm volatile (".insn r 0x0b, 0, 0b0110001, x11, x10, x9");

	//Poly_Enable,`Decode_SUB
	//rs1=4 rs2=2 dst=15	//decode su + v = m  000
	asm volatile (".insn r 0x2b, 0, 0b0000110, x15, x4, x2");

	/////////////////////////////存解密后的明文/////////////////////////
	//wait inst 0010000
	asm volatile (".insn r 0x7b, 0, 0b0010000, x0, x0, x0");
}
